package com.theaf.basemodule.service.impl;

import com.theaf.basemodule.common.api.MenuService;
import com.theaf.basemodule.common.condition.MenuCondition;
import com.theaf.basemodule.common.dto.menu.MenuDTO;
import com.theaf.basemodule.common.model.SysMenu;
import com.theaf.basemodule.common.vo.MenuVO;
import com.theaf.basemodule.dao.MenuDAO;
import com.theaf.basemodule.dao.ResourceDAO;
import com.theaf.core.repo.kit.SimpleSortBuilder;
import com.theaf.core.repo.specification.SqlBuilder;
import com.theaf.core.repo.specification.SqlOperator;
import com.theaf.core.repo.specification.SqlValue;
import com.theaf.core.utils.BeanMapper;
import com.theaf.core.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author:songwenke
 * @Description:资源服务
 * @Date:create in 17:03 2018/1/3
 * @Modified By:
 **/
@Service
public class MenuServiceImpl implements MenuService{
    @Resource
    private MenuDAO menuDAO;

    @Resource
    private ResourceDAO resourceDAO;

    @Override
    public void delete(Long id){
        SysMenu sysMenu = menuDAO.findOne(id);
        if(sysMenu.getType()==SysMenu.TYPE_GROUP){
            //删除菜单组之中的所有菜单组和菜单
            menuDAO.deleteCustom(
                    SqlBuilder.start("levelCode",SqlOperator.OPER.LIKER,
                            menuDAO.subquery(SqlBuilder.start("id",id).setSelects(new String[]{"levelCode"}))));
        }else {
            menuDAO.delete(id);
        }
    }

    @Override
    public List<MenuDTO> findList(MenuCondition condition) {
        SqlBuilder sqlbuilder = new SqlBuilder();
        if(StringUtils.isNotEmpty(condition.getName())||StringUtils.isNotEmpty(condition.getUrl())
                ||StringUtils.isNotEmpty(condition.getModuleName())) {
            sqlbuilder.and(menuDAO.subquery(
                    SqlBuilder.start("name", SqlOperator.OPER.LIKE, SqlValue.parse(condition.getName()))
                            .and("sysResource.name", SqlOperator.OPER.LIKE, SqlValue.parse(condition.getModuleName()))
                            .nestAnd("templateUrl",SqlOperator.OPER.LIKE, SqlValue.parse(condition.getUrl()))
                            .or("controllerUrl", SqlOperator.OPER.LIKER,SqlValue.parse(condition.getUrl())).end()
                            .and("levelCode", SqlOperator.OPER.LIKER,"@levelCode")
                            .setSelect("id")), SqlOperator.OPER.EXISTS, null);
        }
        if(condition.getFilterId()!=null){
            sqlbuilder.and("levelCode",SqlOperator.OPER.NLIKER,menuDAO.subquery(
                    SqlBuilder.start("id",condition.getFilterId())
                            .setSelect("levelCode")));
        }
        if(!condition.isIncludeMenu()){
            sqlbuilder.and("type",1);
        }
        List<SysMenu> sysMenus = menuDAO.findAll(sqlbuilder.gen(), SimpleSortBuilder.generateSort("orderNo"));
        return sysMenus.parallelStream().map(
                n-> fromPo(n)).collect(Collectors.toList());
    }

    @Override
    public List<MenuDTO> findSameLevelList(long id) {
        SysMenu sysMenu = menuDAO.findOne(id);
        List<SysMenu> sysMenus = null;
        if(sysMenu.getSysMenu()!=null) {
            sysMenus = menuDAO.findAll(SqlBuilder.start("sysMenu", sysMenu.getSysMenu()).gen(),
                    SimpleSortBuilder.generateSort("orderNo"));
        }else{
            sysMenus = menuDAO.findAll(SqlBuilder.start("sysMenu", SqlOperator.OPER.NULL,null).gen(),
                    SimpleSortBuilder.generateSort("orderNo"));
        }
        return sysMenus.parallelStream().map(
                n-> fromPo(n)).collect(Collectors.toList());
    }

    private MenuDTO fromPo(SysMenu sysMenu){
        MenuDTO menuDTO = BeanMapper.map(sysMenu,MenuDTO.class);
        if(sysMenu.getSysMenu()!=null){
            menuDTO.setPid(sysMenu.getSysMenu().getId());
            menuDTO.setPname(sysMenu.getSysMenu().getName());
        }
        if(sysMenu.getSysResource()!=null){
            menuDTO.setModuleId(sysMenu.getSysResource().getId());
            menuDTO.setModuleName(sysMenu.getSysResource().getName());
        }
        menuDTO.setTypeName(sysMenu.getType()==1?"目录":"菜单");
        return menuDTO;
    }

    @Override
    public List<MenuDTO> findListByUserId(long userId) {
        return menuDAO.findUserMenu(userId).parallelStream().map(n->fromPo(n)).collect(Collectors.toList());
    }

    @Override
    public MenuDTO findById(Long id) {
        return fromPo(menuDAO.findOne(id));
    }

    @Override
    public long save(MenuVO vo) {
        SysMenu sysMenu = menuDAO.findByIdNewIfisNull(vo.getId());
        if(vo.getId()!=null&&!vo.getEnable().equals(sysMenu.getEnable())){
            menuDAO.findAll(SqlBuilder.start("levelCode",SqlOperator.OPER.LIKER,menuDAO.subquery(
                    SqlBuilder.start("id",vo.getId()).setSelects(new String[]{"levelCode"}))).gen()).forEach(n->{
                ((SysMenu)n).setEnable(vo.getEnable());
            });
        }
        BeanMapper.copy(vo,sysMenu);
        sysMenu.setSysMenu(vo.getPid()==null?null:menuDAO.findOne(vo.getPid()));
        sysMenu.setSysResource(vo.getModuleId()==null?null:resourceDAO.findOne(vo.getModuleId()));
        menuDAO.initLevel(sysMenu,"levelCode","id","sysMenu.id");
        menuDAO.save(sysMenu);
        return sysMenu.getId();
    }

    @Override
    public void saveSort(List<Long> ids) {
        int i=1;
        for(Long id:ids){
            SysMenu sysMenu = menuDAO.findOne(id);
            sysMenu.setOrderNo(i++);
            menuDAO.save(sysMenu);
        }
    }
}
